LCD1602 是一款常見的文字數字型液晶顯示模組,通常用來顯示簡短文字訊息。具有 16 行 2 列的顯示區域,最多同時可以顯示 32 個文字。
我們過去在玩 Arduino 學習版時,常會買 I2C 通訊介面的 LCD1602 模組,這樣與其他元件整合時,就不會整個麵包版都插滿線。
I2C(Inter-Integrated Circuit),中文叫集成电路总线,它是一种串行通信总线,使用多主从架构,是由飞利浦公司在1980年代初设计的,方便了主板、嵌入式系统或手机与周边设备组件之间的通讯。由于其简单性,它被广泛用于微控制器与传感器阵列,显示器,IoT设备,EEPROM等之间的通信。
最重要的功能包括:
只需要两条总线
所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址
I2C是真正的多主设备总线,可提供仲裁和冲突检测
传输速度
标准模式:Standard Mode = 100 Kbps
快速模式:Fast Mode = 400 Kbps
高速模式: High speed mode = 3.4 Mbps
超快速模式: Ultra fast mode = 5 Mbps
最大主设备数:无限制
最大从机数:理论上是127
大白话:一种只用2根线就可以传递很多数据给其它多台设备的方法,这种方法叫I2C
大大减少了MCU上IO的使用
MicroPython 官網上有對於 I2C 傳輸的介紹資料 Software I2C Bus
# I2C 掃描程式
import machine
I2C_SDA_PIN = 23
I2C_SCL_PIN = 22
i2c=machine.I2C(0,sda=machine.Pin(I2C_SDA_PIN), scl=machine.Pin(I2C_SCL_PIN), freq=400000)
print('Scanning I2C bus.')
devices = i2c.scan() # this returns a list of devices
device_count = len(devices)
if device_count == 0:
print('No i2c device found.')
else:
print(device_count, 'devices found.')
for device in devices:
print('Decimal address:', device, ", Hex address: ", hex(device))
執行結果
MPY: soft reboot
Scanning I2C bus.
2 devices found.
Decimal address: 25 , Hex address: 0x19
Decimal address: 39 , Hex address: 0x27
from machine import I2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
i2c = I2C(0, sda=machine.Pin(23), scl=machine.Pin(22), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
lcd.putstr("Hi, WiFiBoy!")
# LCD1602小時鐘
import utime
import machine
from machine import I2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
def test_main():
#Test function for verifying basic functionality
print("Running test_main")
i2c = I2C(0, sda=machine.Pin(23), scl=machine.Pin(22), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
count = 0
lcd.backlight_on()
while True:
lcd.clear()
time = utime.localtime()
lcd.putstr("{year:>04d}/{month:>02d}/{day:>02d} {HH:>02d}:{MM:>02d}:{SS:>02d}".format(year=time[0], month=time[1], day=time[2], HH=time[3], MM=time[4], SS=time[5]))
utime.sleep(1)
count += 1
test_main()
LCD1602 可以顯示的字符集是基於 ASCII 編碼與自行定義的字符。
import utime
from machine import I2C, Pin
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
def test_main():
# Test function for verifying LCD1602 full character set
print("Running LCD1602 full character set")
# 初始化 I2C
i2c = I2C(0, sda=Pin(23), scl=Pin(22), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
lcd.backlight_on()
lcd.clear()
# LCD1602 支援的符號
lcd_chars = []
# 增加自己定義的符號 (0x00 至 0x07)
for x in range(0x00, 0x08):
lcd_chars.append(chr(x))
# 增加標準 ASCII 符號(0x20 至 0x7F)
for x in range(0x20, 0x80):
lcd_chars.append(chr(x))
char_string = ''.join(lcd_chars)
print("Displaying all supported characters.")
# 依次顯示字符
for i in range(0, len(char_string), I2C_NUM_COLS):
lcd.clear()
lcd.putstr(char_string[i:i + I2C_NUM_COLS])
time.sleep(1) # 每秒更新一次
# 執行程式
test_main()
import utime
import machine
from machine import I2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
def write_custom_char(lcd, location, char_map):
location &= 0x07
lcd.hal_write_command(0x40 | (location << 3))
for line in char_map:
lcd.hal_write_data(line)
def custom_char_demo():
custom_chars = [
[0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000], # Heart
[0b00000, 0b01010, 0b00000, 0b00000, 0b10001, 0b01110, 0b00000, 0b00000], # Smiley
[0b00100, 0b01110, 0b11111, 0b00100, 0b00100, 0b00100, 0b00100, 0b00000], # Arrow Up
[0b00100, 0b00100, 0b00100, 0b00100, 0b11111, 0b01110, 0b00100, 0b00000], # Arrow Down
[0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000], # Block
[0b00000, 0b11111, 0b10101, 0b10101, 0b11111, 0b00000, 0b00000, 0b00000], # Checkerboard
[0b00000, 0b11111, 0b10001, 0b10001, 0b11111, 0b00000, 0b00000, 0b00000], # Frame
[0b00000, 0b00000, 0b00100, 0b01110, 0b00100, 0b00000, 0b00000, 0b00000] # Dot
]
i2c = I2C(0, sda=machine.Pin(23), scl=machine.Pin(22), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
for i in range(8):
write_custom_char(lcd, i, custom_chars[i])
lcd.clear()
lcd.putstr("Custom Chars:\n")
for i in range(8):
lcd.putstr(chr(i))
utime.sleep(10)
custom_char_demo()